package com.zhoug.player.core;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.Log;
import android.view.TextureView;

import com.zhoug.player.core.utils.ThreadUtils;
import com.zhoug.player.core.utils.Utils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * @Author: zhoug
 * @Date: 2023/1/11
 * @Description:
 */
public abstract class BaseZPlayer implements ZPlayer {
    private static final String TAG = ">>>BaseZPlayer";
    private static final boolean MUTE_DEF = true;//默认静音
    protected Context mContext;
    protected String mPlayUrl;
    protected int mPlayUrlType;
    protected String mTalkUrl;
    protected PlayListener mPlayListener;//播放监听
    protected CapturePictureListener mCapturePictureListener;//截图监听
    protected VideoRecordListener mVideoRecordListener;//录像监听
    protected PlayProgressListener mPlayProgressListener;//播放进度监听
    protected OnTalkListener mOnTalkListener;//对讲监听
    protected TextureView mTextureView;
    protected boolean mMute = MUTE_DEF;//默认静音
    protected @State int mPlayState = STATE_IDLE;//播放状态
    protected int mRenderMode = RENDER_MODE_FULL_FILL_SCREEN;
    private volatile boolean mReleased = false;//标记已经释放了播放器资源

    /**
     * 设置上下文
     *
     * @param context
     */
    @Override
    public void setContext(@NonNull Context context) {
        this.mContext = context;
    }

    /**
     * 设置播放url
     *
     * @param url
     */
    @Override
    public void setPlayUrl(@Nullable String url) {
        this.mPlayUrl = url;
    }

    /**
     * @param type {@link  PlayUrlUtils#TYPE_FLV}
     */
    @Override
    public void setPlayUrlType(int type) {
        this.mPlayUrlType = type;
    }

    /**
     * 获取播放地址
     *
     * @return
     */
    @Override
    public String getPlayUrl() {
        return mPlayUrl;
    }

    /**
     * 设置显示页面
     *
     * @param textureView
     */
    @Override
    public void setVideoTextureView(@Nullable TextureView textureView) {
        this.mTextureView = textureView;
    }

    /**
     * 设置播放渲染模式
     * 渲染模式有两种:
     * {@link #RENDER_MODE_FULL_FILL_SCREEN}平铺模式：视频画面将会按照比例铺满屏幕，多余部分会被裁减掉，此模式下不会有黑边。
     * {@link #RENDER_MODE_ADJUST_RESOLUTION}自适应模式：视频画面将等比例缩放，会居中显示，此模式可能会有黑边。
     *
     * @param renderMode {@link #RENDER_MODE_FULL_FILL_SCREEN,#RENDER_MODE_ADJUST_RESOLUTION}
     */
    @Override
    public void setRenderMode(int renderMode) {
        this.mRenderMode = renderMode;
        if (mTextureView instanceof VideoRatioTextureView) {
            ((VideoRatioTextureView) mTextureView).setRenderMode(renderMode);
        }
    }


    @Override
    public void preLoad() {

    }

    /**
     * 设置播放渲染模式
     *
     * @return
     */
    @Override
    public int getRenderMode() {
        return this.mRenderMode;
    }

    /**
     * 设置对讲url
     *
     * @param talkUrl
     */
    @Override
    public void setTalkUrl(String talkUrl) {
        this.mTalkUrl = talkUrl;
    }

    /**
     * 设置静音
     *
     * @param mute true:静音,false:非静音
     */
    @Override
    public void setMute(boolean mute) {
        this.mMute = mute;
    }

    /**
     * 是否是静音
     *
     * @return
     */
    @Override
    public boolean isMute() {
        return mMute;
    }

    @Override
    public long getCurrentPosition() {
        return 0;
    }

    @Override
    public long getDuration() {
        return 0;
    }

    /**
     * 播放监听
     *
     * @param playListener
     */
    @Override
    public void setPlayListener(@Nullable PlayListener playListener) {
        this.mPlayListener = playListener;
    }

    /**
     * 设置截屏回掉
     *
     * @param capturePictureListener
     */
    @Override
    public void setCapturePictureListener(@Nullable CapturePictureListener capturePictureListener) {
        this.mCapturePictureListener = capturePictureListener;
    }

    /**
     * 设置视频录制回掉
     *
     * @param videoRecordListener
     */
    @Override
    public void setVideoRecordListener(@Nullable VideoRecordListener videoRecordListener) {
        this.mVideoRecordListener = videoRecordListener;
    }

    /**
     * 视频播放进度监听
     *
     * @param playProgressListener
     */
    @Override
    public void setPlayProgressListener(@Nullable PlayProgressListener playProgressListener) {
        this.mPlayProgressListener = playProgressListener;
    }

    @Override
    public void setOnTalkListener(OnTalkListener onTalkListener) {
        this.mOnTalkListener = onTalkListener;
    }


    /**
     * 释放资源,注意请把所有setXXX的数据设置为空
     */
    @Override
    public void release() {
        mReleased=true;
        mContext = null;
        mTextureView = null;
        mPlayListener = null;
        mPlayUrl = null;
        mMute = MUTE_DEF;
        mPlayState = STATE_IDLE;
    }

    @Override
    public boolean isReleased() {
        return mReleased;
    }

    /**
     * 是否正在播放
     *
     * @return
     */
    @Override
    public boolean isPlaying() {
        return mPlayState == STATE_PLAYING;
    }

    /**
     * 获取播放状态
     *
     * @return
     */
    @Override
    public @State int getPlaySate() {
        return mPlayState;
    }

    /**
     * 截屏,结果在{@link #setCapturePictureListener(CapturePictureListener)}中回掉
     *
     * @param path 截屏成功后保存的路径
     */
    @Override
    public void capturePicture(@NonNull String path) {
        Bitmap bitmap = null;
        if (mTextureView != null) {
            bitmap = mTextureView.getBitmap();
        }
        if (bitmap != null) {
            Bitmap bitmapTemp = bitmap;
            ThreadUtils.getExecutorService().execute(() -> {
                boolean success = Utils.keepBitmap(bitmapTemp, 100, path);
                if (mCapturePictureListener != null) {
                    ThreadUtils.runMainThread(() -> {
                        Utils.scannerFile(mContext, path);
                        if (mCapturePictureListener != null) {
                            mCapturePictureListener.onCapturePictureResult(true, bitmapTemp, path);
                        }
                    });
                }

            });
        } else {
            if (mCapturePictureListener != null) {
                ThreadUtils.runMainThread(() -> {
                    if (mCapturePictureListener != null) {
                        mCapturePictureListener.onCapturePictureResult(false, null, path);
                    }
                });
            }

        }

    }

    @Override
    public boolean isRecording() {
        return false;
    }

    /**
     * 开启电子放大
     *
     * @param oRect
     * @param curRect
     */
    @Override
    public void openDigitalZoom(Rect oRect, Rect curRect) {

    }

    /**
     * 关闭电子放大
     */
    @Override
    public void closeDigitalZoom() {

    }

    //###########下面定义公用方法################

    /**
     * 播放状态改变时调用
     *
     * @param status
     */
    protected void callStatusChange(@State int status) {
        if (mPlayState == status) return;
        mPlayState = status;
//        Log.d(TAG, "invokeStatusChange:" + Thread.currentThread().getName());
        if (mPlayListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mPlayListener != null) {
                    mPlayListener.onPlayStatusChange(status);
                }
            });
        }
    }
    /**
     * 视频输出画面回掉
     *
     */
    protected void callVideoOutput() {
        if (mPlayListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mPlayListener != null) {
                    mPlayListener.onVideoOutput();
                }
            });
        }
    }


    /**
     * 播放错误时调用
     *
     * @param
     */
    protected void callError(@PlayError.ErrorCode int code) {
        if (mPlayListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mPlayListener != null) {
                    mPlayListener.onPlayError(code, PlayError.getErrorMessage(code));
                }
            });
        }
    }

    /**
     * 播放错误时调用
     *
     * @param error
     */
    protected void callError(@PlayError.ErrorCode int code, String error) {
        Log.e(TAG, "playError:" + error);
        if (mPlayListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mPlayListener != null) {
                    mPlayListener.onPlayError(code, error);
                }
            });
        }
    }

    /**
     * 录制视频开始时调用
     */
    protected void callRecordVideoStart() {
        Log.d(TAG, "callRecordVideoStart:开始录像");
        if (mVideoRecordListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mVideoRecordListener != null) {
                    mVideoRecordListener.onStartRecordVideo();
                }
            });
        }
    }

    /**
     * 录制视频结束时调用
     *
     * @param path
     */
    protected void callRecordVideoStop(String path) {
        Log.d(TAG, "callRecordVideoStop:结束录像");
        if (mVideoRecordListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mVideoRecordListener != null) {
                    mVideoRecordListener.onStopRecordVideo(path);
                }
            });
        }
    }

    /**
     * 录制视频发生错误时调用
     *
     * @param error
     */
    protected void callRecordVideoError(String error) {
        Log.e(TAG, "callRecordVideoError:录制视频发生错误:" + error);
        if (mVideoRecordListener != null) {
            ThreadUtils.runMainThread(() -> {
                if (mVideoRecordListener != null) {
                    mVideoRecordListener.onErrorRecordVideo(error);
                }
            });
        }
    }


}
